﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Xml.Serialization;
using System.ComponentModel;

namespace XEvents.Library
{
    /// <summary>
    /// Contains an instance of a Session Event
    /// </summary>
    [Serializable]
    public class EventSessionEvent
    {
        
        internal EventSessionEvent(server_event_session_event sese, EventSession ses)
        {
            this.name = sese.package + "." + sese.name;
            this.predicate = sese.predicate;
            this.actions = (List<string>)(from sesa in ses.Server.sessiondata.server_event_session_actions
                                                       where sesa.event_session_id == sese.event_session_id
                                                       && sesa.event_id == sese.event_id
                                                       select sesa.package+"."+sesa.name).ToList();
            this.parent = ses;
        }
        public EventSessionEvent()
        { }

        private EventSession parent = new EventSession(null);
        private string name = string.Empty;
        private List<string> actions = new List<string>();
        private string predicate = string.Empty;

        /// <summary>
        /// Check if the current object is equal to the object for comparison
        /// </summary>
        /// <param name="obj">EventSessionEvent object for comparison</param>
        public override bool Equals(object obj)
        {
            EventSessionEvent e = (EventSessionEvent)obj;
            if (e == null)
                return false;
            else
            {
                if (e.actions.Count != actions.Count)
                    return false;
                foreach (string action in e.actions)
                {
                    if (!actions.Contains(action))
                        return false;
                }
                if (e.Predicate != Predicate)
                    return false;
                if (e.name != name)
                    return false;
                if (e.predicate != predicate)
                    return false;
            }
            return true;
        }

        /// <summary>
        /// Override method of GetHashCode returning the hash code for this object.
        /// </summary>
        public override int GetHashCode()
        {

            return name.GetHashCode() ^ actions.GetHashCode() ^ predicate.GetHashCode();
        }

        /// <summary>
        /// Returns the Event Name
        /// </summary>
        [CategoryAttribute("Event Information"), DescriptionAttribute("The Name of the Event.")]
        [XmlAttribute("Name")]
        public string Name
        {
            get { return name; }
            set
            {
                name = value;
                parent.isdirty = true;
            }
        }

        /// <summary>
        /// Returns the Event Session that this Event belongs to.
        /// </summary>
        [CategoryAttribute("Event Information"), DescriptionAttribute("The parent Event Session for the Event.")]
        [XmlAttribute("Parent")]
        public EventSession Parent
        {
            get { return parent; }
        }


        /// <summary>
        /// Returns the SessionPredicate of this EventSessionEvent.
        /// </summary>
        [CategoryAttribute("Event Information"), DescriptionAttribute("The predicate for the Event Session Event.")]
        [XmlAttribute("Predicate")]
        public string Predicate
        {
            get { return predicate; }
            set { predicate = value;
            parent.isdirty = true;
            }
        }

        [CategoryAttribute("Event Information"), DescriptionAttribute("The Action List for the Event Session Event.")]
        [XmlIgnore()]
        public List<string> Actions
        {
            get { return actions; }
            set { actions = value;
            parent.isdirty = true;
            }
        }


        /// <summary>
        /// Adds a SessionAction the SessionEvents Collection
        /// </summary>
        /// <param name="action">The SessionAction to add to the collection</param>
        public bool AddAction(string action)
        {
            if (!this.actions.Contains(action))
            {
                this.actions.Add(action);
                parent.isdirty = true;
                return true;
            }
            return false;
        }

        /// <summary>
        /// Removes a SessionAction from the collection.
        /// </summary>
        /// <param name="action">SessionAction to remove from the collection</param>
        public bool RemoveAction(string action)
        {
            if (this.actions.Contains(action))
            {
                this.actions.Remove(action);
                parent.isdirty = true;
                return true;
            }
            return false;
        }

        /// <summary>
        /// Returns the Action string for this Event.
        /// </summary>
        [CategoryAttribute("Event Information"), DescriptionAttribute("The Action String for the Event Session Event.")]
        [XmlAttribute("ActionString")]
        public string ActionString
        {
            get
            {
                string retval = string.Empty;

                foreach (string str in actions)
                {
                    retval += str + ", ";
                }

                if (retval.EndsWith(", "))
                    retval = retval.Substring(0, retval.Length - 2);

                return retval;
            }
            set
            {
            }
        }

        /// <summary>
        /// Returns the Action string for this Event.
        /// </summary>
        private string GetActionsString()
        {
            string retval = string.Empty;

            foreach (string str in actions)
            {
                retval += str + ", ";
            }

            if (retval.EndsWith(", "))
                retval = retval.Substring(0, retval.Length - 2);

            return retval;
        }

        /// <summary>
        /// Generate ADD EVENT Script for this event.
        /// </summary>
        public string Script()
        {
            string retval = string.Format(@"ADD EVENT {0}(", name);

            if (actions.Count > 0)
            {
                retval += "\r\n" + string.Format("     ACTION ({0})", GetActionsString()) ;
            }

            if (predicate != null)
                if (predicate != string.Empty)
                {
                    retval += "\r\n" + string.Format("     WHERE ({0})", predicate);
                }
            if (retval.EndsWith("("))
                return retval.Substring(0, retval.Length - 1) + ",";
            else
                return retval + "),";
        }

        /// <summary>
        /// Generate the DROP EVENT script for this Event.
        /// </summary>
        public string ScriptDrop()
        {
            return string.Format(@"DROP EVENT {0},", name);
        }
    }
}

